home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Topik
/
Topik - Disk 37 - Games 3 (19xx)(Topik Public Domain)(PD)[WB].zip
/
Topik - Disk 37 - Games 3 (19xx)(Topik Public Domain)(PD)[WB].adf
/
RUMMY
/
SOURCE
/
playgame.c.pp
/
playgame.c
Wrap
C/C++ Source or Header
|
1991-02-24
|
14KB
|
518 lines
/* PLAYGAME.C
* This file has the functions to play a game, including the functions to
* play a game, manipulate the pack.
*/
#include <proto/all.h>
#include <stdlib.h>
#include <math.h>
#include <intuition/intuition.h>
#include <string.h>
#include "defns.h"
#include "externs.h"
VOID playgame(USHORT nplr)
{
ULONG pln=0,nc=0,win=0;
USHORT nextplr,startplr=1,i,j,hand=0,nhp;
stdgad[5].Flags &= ~SELECTED; stdgad[6].Flags &= ~SELECTED;
AddGList(wind,&stdgad[3],-1,5,NULL);
RefreshGList(&stdgad[3],wind,NULL,5);
initplrs();
exgm=0;
if(!mandeal)
{ /*pack will be reinitialised in manualdeal()*/
if(initpack[BEFOREGAME]) initialisepack();
if(shufpack[BEFOREGAME]) shuffle();
}
while(!quit && !exgm && ++hand<=numhand)
{
for(pln=1,nhp=0;pln<=nplr;pln++)
{
if(plr[pln]->manctrl) nhp++;
plr[pln]->turn=0;
stci_d(out,plr[pln]->score);
TXTOUT(270,plr[pln]->yc+SCTPY,1,0,out)
stci_d(out,plr[pln]->wins);
TXTOUT(270,plr[pln]->yc+NWTPY,1,0,out)
for(i=1;i<=52;i++) plr[pln]->mem[i]=UNKNOWN;
}
win=0;
nextplr=startplr;
if(!mandeal)
{/*pack will be reinitialised in manualdeal()*/
if(initpack[BEFOREHAND]) initialisepack();
if(shufpack[BEFOREHAND]) shuffle();
}
if(!mandeal || !manualdeal(nplr)) /*autodeal*/
{
for(nc=1;nc<=7;nc++)
for(pln=1;pln<=nplr;pln++)
{
plr[pln]->hand[nc]=NEXTFDP;
plr[pln]->mem[CARD2(plr[pln]->hand[nc])] = CURRPLRHOLDS;
}
plr[1]->nchld=plr[2]->nchld=plr[3]->nchld=7;
for(pln=1;pln<=nplr;pln++) hsort(plr[pln]->hand,plr[pln]->nchld);
}
PUTFUP(NEXTFDP);
DrawImage(wind->RPort,packim[0][CARD2(fup[fuptc])],FUPX,FUPY);
DrawImage(wind->RPort,packim[0][0],FDPX,FDPY);
for(pln=1;pln<=nplr;pln++) if(plr[pln]->viewcard) disphand(plr[pln]);
else hidecards(plr[pln]);
while(!quit && !exgm && !win)
{
plr[nextplr]->turn++;
SETPTR(ptrs[nextplr])
if((plr[nextplr]->level+10)<rand()%21) corrupt(plr[nextplr]); /*corrupt player memory*/
if(plr[nextplr]->manctrl)
manturn(plr[nextplr],plr[nextplr==nplr?1:nextplr+1],
nplr==2?NULL:plr[nextplr==1?nplr:nextplr-1],nhp);
else
{
OffMenu(wind,0x0020); /*reorder off*/
OffMenu(wind,0xf862); /*modmem off*/
OffMenu(wind,0x0040); /*about off*/
autoturn(plr[nextplr],plr[nextplr==nplr?1:nextplr+1],
nplr==2?NULL:plr[nextplr==1?nplr:nextplr-1]);
OnMenu(wind,0x0020); /*reorder on*/
OnMenu(wind,0xf862); /*modmem on*/
OnMenu(wind,0x0040); /*about on*/
}
win = plr[nextplr]->nchld ?0 :nextplr;
nextplr = nextplr==nplr ?1 :nextplr+1; /*another player's turn*/
}
SETPTR(ptrs[0])
if(win) for(i=1;i<=nplr;i++) disphand(plr[i]);
/*return cards to pack and update losers scores*/
while(fuptc>0) PUTFDP(NEXTFUP); /*return face up pack to main pack*/
for(pln=1;pln<=nplr;pln++)
while(plr[pln]->nchld) plr[pln]->score+=(PUTFDP(NEXTPLC(plr[pln]))).n;
for(i=0;i<=5 && fupset[i]->ncard!=0;i++)
{ /*return cards from face up sets*/
for(j=1;j<=14;j++)
if(!CDEQU(fupset[i]->cards[j],nulcard))
{
PUTFDP(fupset[i]->cards[j]);
fupset[i]->cards[j]=nulcard;
}
fupset[i]->ncard=0;
}
if(win)
{/*continuous mode will not display round winners*/
plr[win]->wins++;
if(!contplay) displaywin(plr[win],nplr,hand,numhand);
}
DrawImage(wind->RPort,packim[0][0],FUPX,FUPY);
startplr = startplr==nplr ?1 :startplr+1; /*next plr goes first in next game*/
DrawImage(wind->RPort,&setrem,0,0); /*remove submitted sets*/
sortdispset(); /*remove set gadgets*/
for(pln=1;pln<=nplr;pln++)
{
DrawImage(wind->RPort,&handrem,0,plr[pln]->yc+HANDTOP);
TXTOUT(270,plr[pln]->yc+HVTPY,1,0," ");
TXTOUT(270,plr[pln]->yc+NWTPY,1,0," ");
TXTOUT(270,plr[pln]->yc+SCTPY,1,0," ");
TXTOUT(270,plr[pln]->yc+NWTPY+9,1,0," ");
}
}
displayresult(nplr); /*overall result still displayed in continuous mode*/
RemoveGList(wind,&stdgad[3],5);
RefreshGList(&stdgad[3],wind,NULL,5);
}
VOID initplrs()
{ /*Initialise for start of game*/
register USHORT p,c;
for(p=1;p!=4;p++)
{
plr[p]->score = 0;
for(c=1;c!=53;c++) plr[p]->mem[c]=UNKNOWN;
for(c=0;c!=8;c++) plr[p]->hand[c]=nulcard;
plr[p]->nchld = 0;
plr[p]->wins = 0;
}
for(p=0;p!=6;p++)
{
fupset[p]->ncard=0;
for(c=1;c!=15;c++) fupset[p]->cards[c]=nulcard;
}
}
VOID initialisepack()
{
register USHORT s,n,t;
for(s=DM;s<=SP;s++)
for(n=ACE;n<=KING;n++)
{
fdp[t=s*13+n].s=s;
fdp[t].n=n;
}
fdptc=52;fuptc=0;
}
VOID shuffle()
{
register USHORT mid,nb,top,nt,nc,cnt; /*, nextbottom,,nexttop,destination pos*/
register long dec;
USHORT pass=0;
struct card tpack[53]; /*temporary pack*/
mid = fdptc >> 1; /*middle of face down pack*/
top = fdptc;
cont = 0;
TXTOUT(MESX,MESY,1,0,"Select Continue....")
while(!cont && !quit && !exgm && ++pass<100)
{
nb=mid; nt=top; nc=0;
while(nb && nt>mid)
{
dec = rand(); /*random number*/
for(cnt=32;cnt && nb && nt>mid;cnt--)
if(!((dec>>=1)&1)) tpack[++nc]=fdp[nb--]; /*card from lower half of pack*/
else tpack[++nc]=fdp[nt--]; /*card from upper half of pack*/
}
if(!nb) while(nt>mid) tpack[++nc]=fdp[nt--]; /*copy rest of top half*/
else while(nb) tpack[++nc]=fdp[nb--]; /*copy rest of bottom half*/
/*shuffle back to fdp[]*/
nb=mid; nt=top; nc=0;
while(nb && nt>mid)
{
dec = rand();
for(cnt=32;cnt && nb && nt>mid;cnt--)
if((dec>>=1)&1) fdp[++nc]=tpack[nt--]; /*from top half*/
else fdp[++nc]=tpack[nb--]; /*bottom half*/
}
if(!nb) while(nt>mid) fdp[++nc]=tpack[nt--]; /*copy top*/
else while(nb) fdp[++nc]=tpack[nb--];
}
}
USHORT manualdeal(USHORT nplr)
{
struct IntuiMessage *msg;
struct Gadget *gaddr;
register USHORT pln=1,i,pos;
register ULONG class,gid;
USHORT fin=0,cardno=0,rval=0;
initcardgads();
initialisepack();
SETPTR(ptrs[1])
Request(&mdreq,wind);
while(!fin)
{
Wait(1<<mp->mp_SigBit);
while(msg=(struct IntuiMessage *)GetMsg(mp))
{
class=msg->Class;
gaddr=(struct Gadget *)msg->IAddress;
ReplyMsg((struct Message *)msg);
if(class==GADGETUP)
{
gid=gaddr->GadgetID;
if(gid>CARDG && gid<=CARDG+52)
{
if(cardgads[cardno=gid-CARDG].Flags&SELECTED)
{
if(plr[pln]->nchld<7)
{ /*add card to hand*/
plr[pln]->hand[++(plr[pln]->nchld)]=fdp[cardno];
disphand(plr[pln]);
}
else
{ /*deselect card*/
pos=RemoveGadget(wind,&cardgads[cardno]);
cardgads[cardno].Flags &= ~SELECTED;
AddGList(wind,&cardgads[cardno],pos,1,&mdreq);
if(cardno<=13) RefreshGList(&cardgads[1],wind,&mdreq,13);
else if(cardno<=26) RefreshGList(&cardgads[14],wind,&mdreq,13);
else if(cardno<=39) RefreshGList(&cardgads[27],wind,&mdreq,13);
else RefreshGList(&cardgads[40],wind,&mdreq,13);
}
}
else if(!(cardgads[cardno].Flags&SELECTED) && plr[pln]->nchld)
{ /* remove card from hand*/
for(i=1;i<=plr[pln]->nchld && !CDEQU(plr[pln]->hand[i],fdp[cardno]);i++);
if(CDEQU(plr[pln]->hand[i],fdp[cardno]))
{
plr[pln]->hand[i]=nulcard;
compacthand(plr[pln]->hand,&plr[pln]->nchld);
REMHAND(plr[pln]);
disphand(plr[pln]);
}
}
}
else if(gid==MDACCEPTG)
{ /*disable gadgets and remove selected cards from pack*/
pos=RemoveGList(wind,&cardgads[1],52);
for(i=1;i<=plr[pln]->nchld;i++)
{
cardno=CARD2(plr[pln]->hand[i]);
cardgads[cardno].Flags |= GADGDISABLED;
fdp[cardno]=nulcard;
plr[pln]->mem[cardno]=CURRPLRHOLDS;
}
AddGList(wind,&cardgads[1],pos,52,&mdreq);
RefreshGList(&cardgads[1],wind,&mdreq,52);
if(pln!=nplr)
{ /*set new ptr in here*/
pln++;
SETPTR(ptrs[pln])
}
else
{
fin=rval=1;
EndRequest(&mdreq,wind);
compacthand(fdp,&fdptc);
if(shufpack[BEFOREGAME] || shufpack[BEFOREHAND]) shuffle();
}
}
else if(gid==MDAUTODG)
{
initialisepack();
if(shufpack[BEFOREGAME] || shufpack[BEFOREHAND]) shuffle();
plr[1]->nchld=plr[2]->nchld=plr[3]->nchld=0;
fin=1;
rval=0;
}
}
}
}
SETPTR(ptrs[0])
/*restore original pointer*/
return rval;
}
struct card rvspk()
{ /*only use NEXTFDP from within another macro when it is known that
rvspk() cannot be called*/
struct card tc,c;
USHORT n;
tc=fdp[1]; /*top card*/
fdptc=0;
while(fuptc)
{
c=PUTFDP(NEXTFUP);
plr[1]->mem[n=CARD2(c)] &= ~GONEPAST;
plr[2]->mem[n] &= ~GONEPAST;
plr[3]->mem[n] &= ~GONEPAST;
}
shuffle();
return tc;
}
VOID displaywin(p,nplr,r,nr)
struct playerinfo *p;
USHORT nplr,r,nr;
{
struct IntuiMessage *msg;
register USHORT fin=0;
stci_d(intbuf[0],plr[1]->score);
stci_d(intbuf[1],plr[2]->score);
stci_d(intbuf[2],plr[3]->score);
stci_d(intbuf[3],r);
stci_d(intbuf[4],nr);
rwtxt[4].IText = p->name;
Request(&rwreq,wind);
while(!fin)
{
Wait(1<<mp->mp_SigBit);
while(msg=(struct IntuiMessage *)GetMsg(mp))
{
if(msg->Class == GADGETUP && ((struct Gadget *)(msg->IAddress))->GadgetID==PROCG) fin=1;
ReplyMsg((struct Message *)msg);
}
}
}
VOID displayresult(USHORT nplr)
{
struct IntuiMessage *msg;
register USHORT fin=0;
struct playerinfo *p;
if(plr[1]->score>plr[2]->score) p=plr[2]; else p=plr[1];
if(nplr==3 && p->score>plr[3]->score) p=plr[3];
switch(p->playernum)
{
case 1: if(p->score==plr[2]->score || nplr==3 && p->score==plr[3]->score) gwreq.ReqText = &gwtxt[2]; /*draw*/
else gwreq.ReqText = &gwtxt[0];
break;
case 2: if(p->score==plr[1]->score || nplr==3 && p->score==plr[3]->score) gwreq.ReqText = &gwtxt[2]; /*draw*/
else gwreq.ReqText = &gwtxt[0];
break;
case 3: if(p->score==plr[1]->score || p->score==plr[2]->score) gwreq.ReqText = &gwtxt[2]; /*draw*/
else gwreq.ReqText = &gwtxt[0];
break;
}
stci_d(intbuf[0],plr[1]->score);
stci_d(intbuf[1],plr[2]->score);
stci_d(intbuf[2],plr[3]->score);
stci_d(intbuf[5],plr[1]->wins);
stci_d(intbuf[6],plr[2]->wins);
stci_d(intbuf[7],plr[3]->wins);
gwtxt[1].IText = p->name;
Request(&gwreq,wind);
while(!fin)
{
Wait(1<<mp->mp_SigBit);
while(msg=(struct IntuiMessage *)GetMsg(mp))
{
if(msg->Class == GADGETUP && ((struct Gadget *)(msg->IAddress))->GadgetID==PROCG) fin=1;
ReplyMsg((struct Message *)msg);
}
}
}
VOID reorder(struct playerinfo *p)
{
struct IntuiMessage *msg;
struct Gadget *gaddr;
register USHORT n,pos,gpos;
register ULONG class,gid;
struct card t[8];
OffMenu(wind,0x0020); /*reorder off*/
OffMenu(wind,0xf862); /*modmem off*/
OffMenu(wind,0x0040); /*about off*/
gpos=RemoveGList(wind,&stdgad[3],5);
handgads(p->nchld,p->yc); /*reset gadgets*/
TXTOUT(MESX,MESY,1,0,"Select For Left to Right Display")
for(n=p->nchld;n && !quit && !exgm;)
{
Wait(1 << mp->mp_SigBit);
while(msg=(struct IntuiMessage *)GetMsg(mp))
{
class=msg->Class;
gaddr=(struct Gadget *)(msg->IAddress);
ReplyMsg((struct Message *)msg);
if(class==GADGETUP && (gid=gaddr->GadgetID)>=HANDG1 && gid<=HANDG7)
{
t[n--]=p->hand[gid-HANDG1+1];
pos=RemoveGadget(wind,gaddr);
gaddr->Flags |= GADGDISABLED;
AddGadget(wind,gaddr,pos);
}
}
}
if(!quit && !exgm)
{
for(n=1;n<=p->nchld;n++) p->hand[n]=t[n];
handgads(p->nchld,p->yc); /*reset gadgets*/
disphand(p);
TXTOUT(MESX,MESY,1,0,"Reorder Complete ")
}
AddGList(wind,&stdgad[3],gpos,5,NULL);
OnMenu(wind,0x0020); /*reorder on*/
OnMenu(wind,0xf862); /*modmem on*/
OnMenu(wind,0x0040); /*about on*/
}
VOID modmem(struct playerinfo *p)
{
struct IntuiMessage *msg;
struct Gadget *gaddr;
register USHORT i,fin=0;
USHORT m[53],pos,cardno=0,t;
ULONG class,gid;
initcardgads();
mmtxt[13].IText = p->name;
for(i=0;i<=7;i++) mmgads[i].Flags &= ~SELECTED;
for(i=1;i!=53;i++) m[i]=p->mem[i];
Request(&mmreq,wind);
while(!fin)
{
Wait(1<<mp->mp_SigBit);
while(msg=(struct IntuiMessage *)GetMsg(mp))
{
gaddr=(struct Gadget *)msg->IAddress;
class=msg->Class;
ReplyMsg((struct Message *)msg);
if(class==GADGETUP)
{
gid=gaddr->GadgetID;
if(gid>CARDG && gid<=CARDG+52)
{
if(cardno && cardno!=(gid-CARDG))
{/* deselect previous card*/
cardgads[cardno].Flags &= ~SELECTED;
if(cardno<=13) RefreshGList(&cardgads[1],wind,&mmreq,cardno+1);
else if(cardno<=26) RefreshGList(&cardgads[14],wind,&mmreq,cardno-12);
else if(cardno<=39) RefreshGList(&cardgads[27],wind,&mmreq,cardno-25);
else RefreshGList(&cardgads[40],wind,&mmreq,cardno-38);
}
pos=RemoveGList(wind,&mmgads[0],8);
RefreshGList(&mmgads[0],wind,&mmreq,8);
t=m[cardno=gid-CARDG];
if(cardgads[cardno].Flags&SELECTED)
{
for(i=0;i<=7;i++)
if((t>>i)&1) mmgads[i].Flags |= SELECTED;
else mmgads[i].Flags &= ~SELECTED;
}
else
{
for(i=0;i<=7;i++) mmgads[i].Flags &= ~SELECTED;
cardno=0; /*no card active*/
}
AddGList(wind,&mmgads[0],pos,8,&mmreq);
RefreshGList(&mmgads[0],wind,&mmreq,8);
}
else if(gid==MMSETFG)
{
for(i=0;i<=7;i++)
if(mmgads[i].Flags&SELECTED) m[cardno]|=(1<<i);
else m[cardno]&=~(1<<i);
}
else if(gid==MMACCEPTG)
{
for(i=1;i<=52;i++) p->mem[i]=m[i];
fin=1;
}
else if(gid==MMCANCELG) fin=1;
}
}
}
}
VOID corrupt(struct playerinfo *p)
{ /*corrupt memory of player p*/
long l;
l=rand();
if(l&256) p->mem[l%52] = l&255;
if(l&512) p->mem[(l>>1)%52] |= l&(l>>10);
if(l&1024) p->mem[(l>>5)%52] &= l&(l>>20);
}
VOID initcardgads()
{ /*initialise card gadgets for manual deal and modify memory.*/
register USHORT s,n,d;
for(s=3;s!=-1;s--)
for(n=13;n;n--)
{
d=s*13+n; /*card number*/
cardgads[d]=cardgads[0]; /*initialise*/
cardgads[d].NextGadget = &cardgads[d+1];
if(n==13)
{
cardgads[d].LeftEdge=210;
cardgads[d].Width=64;
cardgads[d].SpecialInfo = (APTR)&wide;
}
else
{
cardgads[d].LeftEdge=cardgads[d+1].LeftEdge - 17;
cardgads[d].Width=17;
cardgads[d].SpecialInfo = (APTR)&narrow;
}
cardgads[d].TopEdge=50*s+20;
cardgads[d].GadgetRender=(APTR)packim[(n==13)?0:1][d];
cardgads[d].GadgetID=d+CARDG;
cardgads[d].Flags &= ~(SELECTED | GADGDISABLED);
}
cardgads[52].NextGadget=NULL;
}